package com.mygdx.snakegame;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import java.util.Random;
import java.util.Vector;

public class PlayState extends State {

    private Sound eatSound;
    private Random random;
    private Snake snake;
    private GameState state;
    private Texture Tbody;
    private Texture Tfood;
    private boolean aBoolean;
    private Texture buttonUp;
    private Texture buttonDown;
    private Texture buttonLeft;
    private Texture buttonRight;
    private int movtimer;
    private int clickX;
    private int clickY;
    private int ScWidth;
    private int ScHeight;
    private int[][] map;
    private Vector<Point> vacancy;
    private Point Food;
    private BitmapFont font;
    int score;
    public PlayState(GameStateManager gsm) {
        super(gsm);
        ScWidth=Gdx.graphics.getWidth();
        ScHeight=Gdx.graphics.getHeight();
        aBoolean=true;
        font=new BitmapFont(Gdx.files.internal("Game.fnt"), Gdx.files.internal("Game_0.png"),false);
        movtimer=0;
        score=0;
        eatSound=Gdx.audio.newSound(Gdx.files.internal("EatSound.ogg"));
        map=new int[36][52];
        vacancy=new Vector<>();
        state=GameState.START;
        Food=new Point();
        random=new Random();
        cam.setToOrtho(false,Config.SWidth,Config.SHeight);
        snake=new Snake();
        Tbody=new Texture("body.jpg");
        Tfood=new Texture("food.jpg");
        buttonUp=new Texture("ButtonUp.png");
        buttonDown=new Texture("ButtonDown.png");
        buttonLeft=new Texture("ButtonLeft.png");
        buttonRight=new Texture("ButtonRight.png");
        generateFood();
        Gdx.gl.glClearColor(1,1,1,1);
    }

     String setStr()
    {
        if (aBoolean == true) {
            return "On";
        }else{
            return "Off";
        }
    }

    void generateFood(){
        for(int y=0;y<36;y++){
            for(int x=0;x<52;x++)
            {
                map[y][x]=0;
            }
        }
        vacancy.clear();
        for(int i=0;i<snake.bodies.size();i++)
        {
            map[snake.bodies.get(i).y][snake.bodies.get(i).x]=1;
        }
        for(int y=1;y<35;y++){
            for(int x=1;x<51;x++)
            {
                if(map[y][x]==0) {
                    vacancy.add(new Point(x, y));
                }
            }
        }
        int randnum=random.nextInt(vacancy.size());
        Food.x=vacancy.get(randnum).x;
        Food.y=vacancy.get(randnum).y;
    }

    @Override
    public void handleinput() {
        if(Gdx.input.justTouched()) {
            clickX=Gdx.input.getX()*960/ScWidth;
            clickY=540*(ScHeight-Gdx.input.getY())/ScHeight;
            if(state==GameState.START)
            {
                state=GameState.ING;
            }
            else if(state==GameState.OVER)
            {
                score=0;
                generateFood();
                snake.bodies.clear();
                snake.bodies.add(new Body(26,17,Dir.Up));
                snake.bodies.add(new Body(26,16,Dir.Up));
                snake.bodies.add(new Body(26,15,Dir.Up));
                state=GameState.ING;
            }
            else if(state==GameState.ING) {
                if (clickX > 900 && clickX < 955 && clickY > 75 && clickY < 135) {
                    snake.changeDir(Dir.Right);
                } else if (clickX > 840 && clickX < 900 && clickY > 135 && clickY < 190) {
                    snake.changeDir(Dir.Up);
                } else if (clickX > 840 && clickX < 900 && clickY > 15 && clickY < 70) {
                    snake.changeDir(Dir.Down);
                } else if (clickX > 785 && clickX < 840 && clickY > 75 && clickY < 135) {
                    snake.changeDir(Dir.Left);
                }
            }
            if(clickX>820&&clickX<931&&clickY>511&&clickY<528)
            {
                aBoolean=!aBoolean;
            }
        }
    }

    @Override
    public void update(float dt) {
        handleinput();
        movtimer++;
        if(movtimer==12) {
            movtimer=0;
            if(state!=GameState.OVER) {
                snake.move();
                if(snake.bodies.get(0).x==Food.x&&snake.bodies.get(0).y==Food.y)
                {
                    generateFood();
                    snake.add();
                    if(aBoolean) {
                        eatSound.play();
                    }
                    score++;
                }
                if(snake.death()) {
                    state=GameState.OVER;
                }
            }
        }

    }

    @Override
    public void render(SpriteBatch sb) {
        sb.setProjectionMatrix(cam.combined);
        sb.begin();
        for(int i=0;i<52;i++)
        {
            sb.draw(Tbody,i*15,525);
            sb.draw(Tbody,i*15,0);
        }
        for(int i=1;i<35;i++)
        {
            sb.draw(Tbody,765,15*i);
            sb.draw(Tbody,0,15*i);
        }
        if(state==GameState.ING||state==GameState.OVER) {
            sb.draw(Tfood,Food.x*15,Food.y*15);
            for (int i = 0; i < snake.bodies.size(); i++) {
                sb.draw(Tbody, snake.bodies.get(i).x * 15, snake.bodies.get(i).y * 15);
            }
        }
        else if(state==GameState.START)
        {
            font.draw(sb,"Click to start!",350,270);
        }
        font.draw(sb,"Score:"+score,830,300);
        sb.draw(buttonRight,900,75);
        sb.draw(buttonUp,840,135);
        sb.draw(buttonDown,840,15);
        sb.draw(buttonLeft,785,75);
        font.draw(sb,"Audio:"+setStr(),820,530);
        if(state==GameState.OVER)
        {
            font.draw(sb,"Game Over",370,300);
            font.draw(sb,"Click to restart!",350,230);
        }
        sb.end();
    }
}
